home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 28
/
Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso
/
Aminet
/
game
/
board
/
Crafty-15.19.lha
/
crafty-15.19
/
src
/
learn.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-09-13
|
48KB
|
1,176 lines
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <string.h>
#include "chess.h"
#include "data.h"
#if defined(UNIX)
# include <unistd.h>
#endif
/* last modified 03/11/98 */
/*
********************************************************************************
* *
* LearnBook() is used to accumulate the evaluations for the first N moves *
* out of book. after these moves have been played, the evaluations are then *
* used to decide whether the last book move played was a reasonable choice *
* or not. (N is set by the #define LEARN_INTERVAL definition.) *
* *
* there are three cases to be handled. (1) if the evaluation is bad right *
* out of book, or it drops enough to be considered a bad line, then the book *
* move will have its "learn" value reduced to discourage playing this move *
* again. (2) if the evaluation is even after N moves, then the learn *
* value will be increased, but by a relatively modest amount, so that a few *
* even results will offset one bad result. (3) if the evaluation is very *
* good after N moves, the learn value will be increased by a large amount *
* so that this move will be favored the next time the game is played. *
* *
********************************************************************************
*/
void LearnBook(TREE *tree, int wtm, int search_value, int search_depth, int lv,
int force) {
/*
----------------------------------------------------------
| |
| if we have not been "out of book" for N moves, all |
| we need to do is take the search evaluation for the |
| search just completed and tuck it away in the book |
| learning array (book_learn_eval[]) for use later. |
| |
----------------------------------------------------------
*/
int t_wtm=wtm;
if (!book_file) return;
if (!(learning&book_learning)) return;
if (moves_out_of_book <= LEARN_INTERVAL && !force) {
if (moves_out_of_book) {
book_learn_eval[moves_out_of_book-1]=search_value;
book_learn_depth[moves_out_of_book-1]=search_depth;
}
}
/*
----------------------------------------------------------
| |
| check the evaluations we've seen so far. if they are |
| within reason (+/- 1/3 of a pawn or so) we simply keep |
| playing and leave the book alone. if the eval is much |
| better or worse, we need to update the learning count. |
| |
----------------------------------------------------------
*/
else if (moves_out_of_book == LEARN_INTERVAL+1 || force) {
int move, i, j, learn_value, read;
int secs, interval, last_book_move=-1;
float temp_value;
char cmd[32], buff[80], *nextc;
int best_eval=-999999, best_eval_p=0;
int worst_eval=999999, worst_eval_p=0, save_wtm;
int best_after_worst_eval=-999999, worst_after_best_eval=999999;
struct tm *timestruct;
int n_book_moves[512];
float book_learn[512], t_learn_value;
if (moves_out_of_book < 1) return;
Print(128,"LearnBook() executed\n");
learning&=~book_learning;
interval=Min(LEARN_INTERVAL,moves_out_of_book);
if (interval < 2) return;
for (i=0;i<interval;i++) {
if (book_learn_eval[i] > best_eval) {
best_eval=book_learn_eval[i];
best_eval_p=i;
}
if (book_learn_eval[i] < worst_eval) {
worst_eval=book_learn_eval[i];
worst_eval_p=i;
}
}
if (best_eval_p < interval-1) {
for (i=best_eval_p;i<interval;i++)
if (book_learn_eval[i] < worst_after_best_eval)
worst_after_best_eval=book_learn_eval[i];
}
else worst_after_best_eval=book_learn_eval[interval-1];
if (worst_eval_p < interval-1) {
for (i=worst_eval_p;i<interval;i++)
if (book_learn_eval[i] > best_after_worst_eval)
best_after_worst_eval=book_learn_eval[i];
}
else best_after_worst_eval=book_learn_eval[interval-1];
#if defined(DEBUG)
Print(128,"Learning analysis ...\n");
Print(128,"worst=%d best=%d baw=%d wab=%d\n",
worst_eval, best_eval, best_after_worst_eval, worst_after_best_eval);
for (i=0;i<interval;i++)
Print(128,"%d(%d) ",book_learn_eval[i],book_learn_depth[i]);
Print(128,"\n");
#endif
/*
----------------------------------------------------------
| |
| we now have the best eval for the first N moves out |
| of book, the worst eval for the first N moves out of |
| book, and the worst eval that follows the best eval. |
| this will be used to recognize the following cases of |
| results that follow a book move: |
| |
----------------------------------------------------------
*/
/*
----------------------------------------------------------
| |
| (1) the best score is very good, and it doesn't drop |
| after following the game further. this case detects |
| those moves in book that are "good" and should be |
| played whenever possible. |
| |
----------------------------------------------------------
*/
if (best_eval == best_after_worst_eval) {
learn_value=best_eval;
for (i=0;i<interval;i++)
if (learn_value == book_learn_eval[i])
search_depth=Max(search_depth,book_learn_depth[i]);
}
/*
----------------------------------------------------------
| |
| (2) the worst score is bad, and doesn't improve any |
| after the worst point, indicating that the book move |
| chosen was "bad" and should be avoided in the future. |
| |
----------------------------------------------------------
*/
else if (worst_eval == worst_after_best_eval) {
learn_value=worst_eval;
for (i=0;i<interval;i++)
if (learn_value == book_learn_eval[i])
search_depth=Max(search_depth,book_learn_depth[i]);
}
/*
----------------------------------------------------------
| |
| (3) things seem even out of book and remain that way |
| for N moves. we will just average the 10 scores and |
| use that as an approximation. |
| |
----------------------------------------------------------
*/
else {
learn_value=0;
search_depth=0;
for (i=0;i<interval;i++) {
learn_value+=book_learn_eval[i];
search_depth+=book_learn_depth[i];
}
learn_value/=interval;
search_depth/=interval;
}
if (lv) learn_value=search_value;
if (lv == 0)
learn_value=LearnFunction(learn_value,search_depth,
crafty_rating-opponent_rating,
learn_value<0);
else learn_value=search_value;
/*
----------------------------------------------------------
| |
| first, we are going to find every book move in the |
| game, and note how many alternatives there were at |
| every book move. |
| |
----------------------------------------------------------
*/
save_wtm=wtm;
InitializeChessBoard(&tree->position[0]);
for (i=0;i<512;i++) n_book_moves[i]=0;
wtm=1;
for (i=0;i<512;i++) {
int *mv, cluster, key, test